package cn.jdemo.jsystem.runtime;

import java.io.IOException;

/**
 * @see Runtime#exec(String)
 * @see Runtime#exec(String[])
 *
 * >p>... ...
 *
 * public Process exec(String command)-----在单独的进程中执行指定的字符串命令。
 * public Process exec(String [] cmdArray)---在单独的进程中执行指定命令和变量
 * public Process exec(String command, String [] envp)----在指定环境的独立进程中执行指定命令和变量
 * public Process exec(String [] cmdArray, String [] envp)----在指定环境的独立进程中执行指定的命令和变量
 * public Process exec(String command,String[] envp,File dir)----在有指定环境和工作目录的独立进程中执行指定的字符串命令
 * public Process exec(String[] cmdarray,String[] envp,File dir)----在指定环境和工作目录的独立进程中执行指定的命令和变量
 *
 * Process的几种方法：
 * </p>
 * @see Process#destroy() ：杀掉子进程
 * @see Process#exitValue() : 返回子进程的出口值，值 0 表示正常终止
 * @see Process#getErrorStream() : 获取子进程的错误流
 * @see Process#getInputStream() : 获取子进程的输入流
 * @see Process#getOutputStream() : 获取子进程的输出流
 * @see Process#waitFor() : 使当前线程在必要时等待，直到此对象表示的进程终止。如果子进程已经终止，则此方法立即返回。如果子进程尚未终止，则调用线程将被阻塞，直到子进程退出。(根据惯例，0 表示正常终止)
 *
 * 注意：在java中，调用runtime线程执行脚本是非常消耗资源的，所以切忌不要频繁使用！
 *      在调用runtime去执行脚本的时候，其实就是JVM开了一个子线程去调用JVM所在系统的命令，
 *      其中开了三个通道： 输入流、输出流、错误流，其中输出流就是子线程走调用的通道。
 *
 * process的阻塞：
 *   在runtime执行大点的命令中，输入流和错误流会不断有流进入存储在JVM的缓冲区中，
 *   如果缓冲区的流不被读取被填满时，就会造成runtime的阻塞。
 *   所以在进行比如：大文件复制等的操作时，我们还需要不断的去读取JVM中的缓冲区的流，来防止Runtime的死锁阻塞。
 *
 * @date 2020/12/18
 */
public class Demo04 {
    public static void main(String[] args) throws IOException, InterruptedException {
        // test01();
        // test02();
        test03();
    }

    /**
     * win下doc命令
     * @throws IOException
     */
    public static void test01() throws IOException {
        Process process = Runtime.getRuntime().exec("notepad.exe");//打开windows下记事本
        //Runtime.getRuntime().exec(shutdown -s -t 500); 添加一个60S后自动关闭计算机的计划;
    }

    /**
     * 输出内容
     * mainstart...
     * mainend...
     */
    public static void test02() throws IOException {
        System.out.println(Thread.currentThread().getName()+"start...");
        Process process = Runtime.getRuntime().exec("notepad.exe");
        System.out.println(Thread.currentThread().getName()+"end...");
    }

    /**
     * 手动关闭记事本前，输出内容:
     * mainstart...
     */
    /**
     * 手动关闭记事本前，输出内容:
     * mainstart...
     * mainend...waitForResult:0
     */
    public static void test03() throws IOException, InterruptedException {
        System.out.println(Thread.currentThread().getName()+"start...");
        Process process = Runtime.getRuntime().exec("notepad.exe");
        int waitForResult = process.waitFor();
        System.out.println(Thread.currentThread().getName()+"end..."+"waitForResult:"+waitForResult);
    }
}
